package org.itzixi.netty.utils;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.recipes.locks.InterProcessReadWriteLock;
import org.apache.zookeeper.CreateMode;
import org.apache.zookeeper.data.Stat;
import org.itzixi.pojo.netty.NettyServerNode;
import org.itzixi.utils.JsonUtils;

import java.net.InetAddress;
import java.nio.charset.StandardCharsets;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.atomic.AtomicReference;


@Slf4j
public class ZKUtil {

    public static void registerNettyServer(String nodeName, String ip, int port) throws Exception{
        CuratorFramework client = CuratorConfig.getClient();
        String path = StrUtil.SLASH + nodeName;
        Stat stat = client.checkExists().forPath(path);
        if (stat == null){
            // 为空就创建节点
            client.create().creatingParentsIfNeeded()
                    //创建临时的有序节点
                    .withMode(CreateMode.PERSISTENT)
                    .forPath(path);
        } else {
            log.info("stat:{}", stat);
        }
        NettyServerNode nettyServerNode = new NettyServerNode();
        nettyServerNode.setIp(ip);
        nettyServerNode.setPort(port);
        String nodeJson = JsonUtils.objectToJson(nettyServerNode);
        client.create()
                .withMode(CreateMode.EPHEMERAL_SEQUENTIAL)
                .forPath(path + "/im-", StrUtil.bytes(nodeJson, StandardCharsets.UTF_8));
        log.info("ip为:{}，端口号为：{}的chat-server的服务已经注册到zookeeper", ip, port);

    }

    public static String getLocalIP() throws Exception{
        return InetAddress.getLocalHost().getHostAddress();
    }

    public static void incrementOnlineCount(NettyServerNode serverNode){
        dealOnlineCount(serverNode, 1);
    }

    public static void decrementOnlineCount(NettyServerNode serverNode){
        dealOnlineCount(serverNode, -1);
    }


    /**
     * 在线人数累加1
     * @param serverNode
     * @param count
     */
    public static void dealOnlineCount(NettyServerNode serverNode, int count){
        CuratorFramework client = CuratorConfig.getClient();
        InterProcessReadWriteLock readWriteLock = new InterProcessReadWriteLock(client, "/rw-lock");

        final String parentPath = "/server-list";
        try {
            readWriteLock.writeLock().acquire();
            List<String> nodeChildren = client.getChildren().forPath(parentPath);
            if (CollectionUtil.isEmpty(nodeChildren)) return;
            for (String node : nodeChildren) {
                String nodePath = parentPath + StrUtil.SLASH + node;
                String dataJson = new String(client.getData().forPath(nodePath));
                NettyServerNode nettyServerNode = JsonUtils.jsonToPojo(dataJson, NettyServerNode.class);
                if (nettyServerNode != null && Objects.equals(serverNode.getIp(), nettyServerNode.getIp())
                        && Objects.equals(nettyServerNode.getPort(), serverNode.getPort())){
                    int onlineCounts = nettyServerNode.getOnlineCounts() + count;
                    if (onlineCounts < 0){
                        nettyServerNode.setOnlineCounts(0);
                    } else {
                        nettyServerNode.setOnlineCounts(onlineCounts + count);
                    }

                    String newNodeJson = JsonUtils.objectToJson(nettyServerNode);
                    assert newNodeJson != null;
                    client.setData().forPath(nodePath, newNodeJson.getBytes(StandardCharsets.UTF_8));
                }
            }



        } catch (Exception e) {
            throw new RuntimeException(e);
        } finally {
            try {
                readWriteLock.writeLock().release();
            } catch (Exception e) {
                log.info("释放所资源异常:{},{}", e, e.getMessage());
            }
        }
//        try {
//            nodeChildren = client.getChildren().forPath(parentPath);
//        } catch (Exception e) {
//            log.error("zookeeper获取子节点失败：{},{}", e, e.getMessage());
//            throw new RuntimeException(e);
//        }
//        if (CollectionUtil.isEmpty(nodeChildren)) return;
//        AtomicReference<String> nodePath = new AtomicReference<>("");
//        nodeChildren.stream().map(node -> {
//            try {
//                nodePath.set(parentPath + StrUtil.SLASH + node);
//                byte[] bytes = client.getData().forPath(nodePath.get());
//                return JSONUtil.toBean(StrUtil.str(bytes, StandardCharsets.UTF_8),NettyServerNode.class);
//            } catch (Exception e) {
//                log.error("zookeeper获取子节点数据失败：{},{}", e, e.getMessage());
//                throw new RuntimeException(e);
//            }
//            //
//        }).filter(child -> Objects.equals(serverNode.getIp(), child.getIp()) && Objects.equals(child.getPort(), serverNode.getPort()))
//            .forEach(child -> {
//                // 循环累加
//                int newOnlineCount = child.getOnlineCounts() + count;
//                child.setOnlineCounts(newOnlineCount);
//                String jsonStr = JSONUtil.toJsonStr(child);
//                try {
//                    client.setData().forPath(nodePath.get(), jsonStr.getBytes(StandardCharsets.UTF_8));
//                } catch (Exception e) {
//                    log.error("zookeeper累加在线人数失败：{},{}", e, e.getMessage());
//                    throw new RuntimeException(e);
//                }
//            });

    }
}
